package com.bjx.flow.approve.user.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.bjx.api.system.domain.bo.ExecuteBO;
import com.bjx.api.system.domain.query.UserQuery;
import com.bjx.api.system.domain.vo.UserVO;
import com.bjx.api.system.service.RemoteUserService;
import com.bjx.common.core.constant.FrameConst;
import com.bjx.common.core.domain.R;
import com.bjx.common.core.exception.BJXException;
import com.bjx.flow.approve.user.ApprovalUserDispose;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @desc: 关系解析
 * @author: liushuai
 * @date: 2022/12/2 16:13
 */
@Service("relationDisposeHandler")
@Slf4j
public class RelationDisposeHandler extends ApprovalUserDispose {
    /**
     * 发起人组织职位
     */
    public static final String INITIATOR_ORG_POST = "initiatorOrgPost";

    /**
     * 发起人公司职位
     */
    public static final String INITIATOR_COMPANY_POST = "initiatorCompanyPost";

    /**
     * 发起人组织角色
     */
    public static final String INITIATOR_ORG_ROLE = "initiatorOrgRole";

    /**
     * 发起人公司角色
     */
    public static final String INITIATOR_COMPANY_ROLE = "initiatorCompanyRole";

    /**
     * 自定义组织职位
     */
    public static final String CUSTOM_ORG_POST = "customOrgPost";

    /**
     * 自定义组织角色
     */
    public static final String CUSTOM_ORG_ROLE = "customOrgRole";


    @Resource
    private RemoteUserService remoteUserService;

    @Override
    public void dispose(JSONObject jsonObject, List<UserVO> users) {
        JSONArray jsonArray = jsonObject.getJSONArray("relation");
        if (CollectionUtil.isNotEmpty(jsonArray)) {
            List<ExecuteBO> executes = Convert.toList(ExecuteBO.class, jsonArray);
            if (CollectionUtil.isNotEmpty(executes)) {
                String initiatorOrgId = jsonObject.getStr("initiatorOrg");
                String initiatorCompanyId = jsonObject.getStr("initiatorCompany");
                List<ExecuteBO> org = Optional.ofNullable(jsonObject.getBeanList("org", ExecuteBO.class)).orElse(new ArrayList<>());
                List<ExecuteBO> com = Optional.ofNullable(jsonObject.getBeanList("com", ExecuteBO.class)).orElse(new ArrayList<>());
                Map<Long, List<Long>> comRole = new HashMap<>();
                Map<Long, List<Long>> orgRole = new HashMap<>();
                for (ExecuteBO execute : executes) {
                    switch (execute.getValue()) {
                        case INITIATOR_ORG_POST:
                            org.add(ExecuteBO.builder()
                                    .value(initiatorOrgId)
                                    .postId(execute.getBusinessId())
                                    .build());
                            break;
                        case INITIATOR_COMPANY_POST:
                            com.add(ExecuteBO.builder()
                                    .value(initiatorCompanyId)
                                    .postId(execute.getBusinessId())
                                    .build());
                            break;
                        case INITIATOR_ORG_ROLE:
                            List<Long> roleIds = Optional.ofNullable(orgRole.get(initiatorOrgId)).orElse(new ArrayList<>());
                            roleIds.add(Long.valueOf(execute.getBusinessId()));
                            orgRole.put(Long.valueOf(initiatorOrgId), roleIds);
                            break;
                        case INITIATOR_COMPANY_ROLE:
                            roleIds = Optional.ofNullable(comRole.get(initiatorCompanyId)).orElse(new ArrayList<>());
                            roleIds.add(Long.valueOf(execute.getBusinessId()));
                            comRole.put(Long.valueOf(initiatorCompanyId), roleIds);
                            break;
                        case CUSTOM_ORG_POST:
                            org.add(ExecuteBO.builder()
                                    .value(execute.getCustomOrg())
                                    .postId(execute.getBusinessId())
                                    .build());
                            break;
                        case CUSTOM_ORG_ROLE:
                            roleIds = Optional.ofNullable(orgRole.get(execute.getCustomOrg())).orElse(new ArrayList<>());
                            roleIds.add(Long.valueOf(execute.getBusinessId()));
                            orgRole.put(Long.valueOf(execute.getCustomOrg()), roleIds);
                            break;
                    }
                }
                jsonObject.set("org", org);
                jsonObject.set("com", com);
                //根据公司id和角色id列表查询
                R<List<UserVO>> r = remoteUserService.listUserVOByComAndRoleIds(UserQuery.builder()
                        .queryMap(comRole)
                        .build());
                if(r.getCode() == FrameConst.FAIL.intValue()){
                    log.error("调用远程用户接口失败:{}",r.getMsg());
                    throw new BJXException("调用远程用户接口失败");
                }
                List<UserVO> data = r.getData();
                users.addAll(data);
                //根据组织id和角色id列表查询
                r = remoteUserService.listUserVOByOrgAndRoleIds(UserQuery.builder()
                        .queryMap(orgRole)
                        .build());
                if(r.getCode() == FrameConst.FAIL.intValue()){
                    log.error("调用远程用户接口失败:{}",r.getMsg());
                    throw new BJXException("调用远程用户接口失败");
                }
                data = r.getData();
                users.addAll(data);
            }
        }
        this.executeNext(jsonObject, users);

    }
}
